import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import DataBase from 'src/config/database';
import { Repository, Like, UpdateResult, In } from 'typeorm';
import { Platform } from '../platform/platform.entity';
import { Video } from '../video/video.entity';
import { InternetCelebrityGroup } from './internetCelebrityGroup.entity';
import utils from 'src/common/utils';
import { EnumInternetCelebrityDeleteTagEnum } from './internetCelebrityGroup.enum';
import { UnConcern } from '../unconcern/unconcern.entity';
import { Concern } from '../concern/concern.entity';
import { InternetCelebrity } from '../internetCelebrity/internetCelebrity.entity';
import { Answer } from '../answer/answer.entity';
import { EnumInIc } from '../video/video.enum';
import { InternetCelebrityGroupDeleteInVideo } from '../internetCelebrityGroupDeleteInVideo/internetCelebrityGroupDeleteInVideo.entity';

@Injectable()
export class InternetCelebrityGroupService {
  constructor(
    @InjectRepository(InternetCelebrityGroup)
    private repository: Repository<InternetCelebrityGroup>,
    @InjectRepository(Platform)
    private platformRepository: Repository<Platform>,
    @InjectRepository(UnConcern)
    private unConcernRepository: Repository<UnConcern>,
    @InjectRepository(Concern)
    private concernRepository: Repository<Concern>,
    @InjectRepository(InternetCelebrity)
    private internetCelebrityRepository: Repository<InternetCelebrity>,
    @InjectRepository(Video)
    private videoRepository: Repository<Video>,
    @InjectRepository(Answer)
    private answerRepository: Repository<Answer>,
    @InjectRepository(InternetCelebrityGroupDeleteInVideo)
    private internetCelebrityGroupDeleteInVideoRepository: Repository<InternetCelebrityGroupDeleteInVideo>,
    
  ) {}


  async createIc(ic_group: number, video_id: number){
    console.log(ic_group,'ic_group')
    let db: DataBase = new DataBase()
    let connection = await db.getConnection()
    const queryRunner = connection.createQueryRunner()
    await queryRunner.connect()
    // 开始事务
    await queryRunner.startTransaction()
    try {
      await this.repository.createQueryBuilder(null, queryRunner)
        .update({delete_tag: EnumInternetCelebrityDeleteTagEnum.no})
        .where({id:ic_group})
        .execute()
      if(video_id){
        await this.videoRepository.createQueryBuilder(null, queryRunner)
          .update({in_ic: EnumInIc.yes})
          .where({id: video_id})
          .execute()
      }

      await queryRunner.commitTransaction()
      await queryRunner.release();
    } catch (err) {
      // 有错误做出回滚更改
      await queryRunner.rollbackTransaction()
      await queryRunner.release();
      return err
    }

    // return this.repository.update({id:ic_group}, {delete_tag: EnumInternetCelebrityDeleteTagEnum.no})
  }

  /**
   * 删除虚拟网红
   * @param ic_group 
   * @returns 
   */
  async deleteIc(ic_group: number){
    let findConcerns = await this.repository.query(`
      select distinct wx_user from concern
        where concern_ic_group not in (
        select unconcern.concern_ic_group from unconcern
        where concern_ic_group is not null
      ) and concern.concern_ic_group = ?
    `,[ic_group])
    let findIcInfo = await this.repository.findOne({where:{id: ic_group}})
    if(!findIcInfo){
      return '未找到网红'
    }
    let db: DataBase = new DataBase()
    let connection = await db.getConnection()
    const queryRunner = connection.createQueryRunner()
    await queryRunner.connect()
    // 开始事务
    await queryRunner.startTransaction()
    try {
      //创建关联此网红的人的关联记录
      let unConcernsList = []
      findConcerns.map(e => {
        let unconcern = new UnConcern()
        unconcern.name = findIcInfo.name
        unconcern.create_time = new Date()
        unconcern.concern_ic_group = ic_group
        unconcern.wx_user = e.wx_user
        unConcernsList.push(unconcern)
      })
      if(unConcernsList.length > 0){
        await this.unConcernRepository.createQueryBuilder(null, queryRunner)
          .insert()
          .into(UnConcern)
          .values(unConcernsList)
          .execute()
      }
      //删除所有关联此网红的人
      await this.concernRepository.createQueryBuilder(null, queryRunner).delete().where({concern_ic_group: ic_group}).execute()
      //修改所有视频不进入网红标志
      await this.videoRepository.createQueryBuilder(null, queryRunner).update({in_ic: EnumInIc.no}).where({ic_group: ic_group}).execute()
      
      //删除网红（设置删除标志）
      await this.repository.createQueryBuilder(null, queryRunner)
        .update({delete_tag: EnumInternetCelebrityDeleteTagEnum.yes})
        .where({id: ic_group})
        .execute()
      await queryRunner.commitTransaction()
      await queryRunner.release();
    } catch (err) {
      // 有错误做出回滚更改
      await queryRunner.rollbackTransaction()
      await queryRunner.release();
      return err
    }
  }

  /**
   * 搜索网红
   * @param keyword 
   */
  async search(wx_user: string, keyword: string, skip: number, take: number){
    let dataList = await this.repository.query(`
      select distinct a.id,d.name,b.id as concern_id,a.create_time,d.openid,
        d.avatar_img
        from internet_celebrity_group a
        left join concern b on b.ic_group = a.id and b.wx_user = ?
        inner join internet_celebrity c on c.ic_group = a.id
        inner join wx_user d on d.openid = a.wx_user
        where (d.id = ? or d.name like ?) and a.type = 1
        order by a.create_time desc
        limit ?,?
    `,[wx_user, keyword, `%${keyword}%`, skip, take])

    dataList.filter(e => e.openid == wx_user).map(e => {
      e.disabled_concern = true
      delete e.openid
    })
    return dataList
  }

  /**
   * 网红是否存在
   */
  async isExists(wx_user: string, account: number): Promise<any> {
    let info = await this.repository.query(`
      select d.openid
      from internet_celebrity_group a
      inner join internet_celebrity c on c.ic_group = a.id
      inner join wx_user d on d.openid = a.wx_user
      where d.id = ?
    `, [account])
    if(info.length === 0){
      return {exists:false,message:'网红不存在'}
    }else{
      if(info[0].openid == wx_user) {
        return {exists:false,message:'你不能关注自己'}
      }else{
        return {exists:true}
      }
    }
  }

  /**
   * 查询网红信息和视频
   * @param id
   */
  async findInfo(wx_user: string, id?: number, account?: string): Promise<{info:any, videos: Video[]}>{
    //网红信息
    let info:any = {}
    let videos:Video[] = []
    if(account){
      info = await this.repository.query(`
        select distinct a.id,d.name,b.id as concern_id,d.openid,d.id as user_id,
        d.avatar_img
        from internet_celebrity_group a
        left join concern b on b.ic_group = a.id and b.wx_user = ?
        inner join internet_celebrity c on c.ic_group = a.id
        inner join wx_user d on d.openid = a.wx_user
        where d.id = ? and a.type = 1
      `, [wx_user, account])

      if(info.length > 0){
        if(info[0].openid === wx_user){
          info[0].disabled_concern = true
          delete info[0].openid
        }
      }

      videos = await this.repository.query(`
        select distinct a.id, a.video_url, a.video_cover, c.id as watch_record_id,a.type
        from video a
        inner join internet_celebrity_group b on b.id = a.ic_group
        left join watch_record c on c.video_id = a.id and c.wx_user = ?
        inner join internet_celebrity d on d.ic_group = b.id
        inner join wx_user f on f.openid = a.wx_user
        where f.id = ? and a.check = 1 and a.profit_type = 1 and b.type = 1
      `, [wx_user, account])
    }else{
      info = await this.repository.query(`
        select distinct a.id,d.name,b.id as concern_id,d.openid,d.id as user_id,
        d.avatar_img
        from internet_celebrity_group a
        left join concern b on b.ic_group = a.id and b.wx_user = ?
        inner join wx_user d on d.openid = a.wx_user
        where a.id = ? and a.type = 1
      `, [wx_user, id])

      if(info.length > 0){
        if(info[0].openid === wx_user){
          info[0].disabled_concern = true
          delete info[0].openid
        }
      }

      videos = await this.repository.query(`
        select distinct a.id, a.video_url, a.video_cover, c.id as watch_record_id,a.type
        from video a
        inner join internet_celebrity_group b on b.id = a.ic_group
        left join watch_record c on c.video_id = a.id and c.wx_user = ?
        where b.id = ? and a.check = 1 and a.profit_type = 1 and b.type = 1
      `, [wx_user, id])
    }

    //网红下所有视频
    return {info:info[0],videos}
  }

  
  getIDCard(){
    let id = ''
    let loop = async () => {
      id = utils.randomNumberID(7)
      if(await this.repository.findOne({where:{id_card: id}})){
        loop()
      }
    }
    loop()
    return id
  }

  /**
   * 创建网红
   * @param data
   * @returns
   */
  async create(data: InternetCelebrityGroup): Promise<InternetCelebrityGroup>{
    data.id_card = await this.getIDCard()
    return this.repository.save(data)
  }

  /**
   * 查询是否创建了网红
   * @param wx_user 
   * @param name 
   * @returns 
   */
  findIsExists(wx_user: string, name: string): Promise<InternetCelebrityGroup>{
    return this.repository.findOne({
      where:{
        wx_user:wx_user,
        name:name
      }
    })
  }

  /**
   * 修改网红信息
   * @param data
   * @returns
   */
   update(id: number,name: string): Promise<UpdateResult>{
    return this.repository.update({id:id},{name:name})
  }

  async findAll_ByUser(skip: number, take: number, wx_user: string, keyword: string, ic_group_id?: number): Promise<{data:[],total:number}>{
    let data:any = []
    let total = []

    if(ic_group_id != undefined){
      data = await this.repository.query(`
        select * from internet_celebrity_group
        where id = ?
      `,[ic_group_id])
      total = [{total:1}]
    }else{
      data = await this.repository.query(`
        select * from internet_celebrity_group
        where wx_user = ? and LOWER(name) like ?
        order by id desc
        limit ?,?
      `,[wx_user, `%${keyword.toLocaleLowerCase()}%`, skip, take])

      total = await this.repository.query(`
        select count(1) as total from internet_celebrity_group
        where wx_user = ? and LOWER(name) like ?
      `,[wx_user, `%${keyword.toLocaleLowerCase()}%`, skip, take])
    }

    
    return {data,total:Number(total[0].total)}
  }

  async findAll_ByUser_lib(skip: number, take: number, keyword: string): Promise<{data:[],total:number}>{
    let data:any = []
    let total = []

    data = await this.repository.query(`
      select * from internet_celebrity_group
      where internet_celebrity_group.id not in (
        select platform.ic_group from platform
        inner join setting on setting.value = platform.platform
        where setting.key = 'level3'
      ) and internet_celebrity_group.type = 0
      and LOWER(name) like ?
      order by id desc
      limit ?,?
    `,[`%${keyword.toLocaleLowerCase()}%`, skip, take])

    //查询所有关联的真实网红
    let relaIcList = []
    let whereSql = []
    data.map(e => whereSql.push(`internet_celebrity_group_rela_ic_info.ic_group = ?`))
    if(whereSql.length > 0){
      relaIcList = await this.repository.query(`
        select wx_user.name, internet_celebrity_group_rela_ic_info.ic_group as id, internet_celebrity_group_rela_ic_info.id as rela_ic_info_id 
        from internet_celebrity_group_rela_ic_info
        inner join internet_celebrity_group icg on icg.id = internet_celebrity_group_rela_ic_info.ic_group_rela_ic_info
        inner join wx_user on wx_user.openid = icg.wx_user
        where ${whereSql.join(' or ')}
      `, data.map(e => e.id))
      data.map(e => {
        let findRelaIcList = relaIcList.filter(c => c.id == e.id)
        e.relaIcList = findRelaIcList
      })
    }

    total = await this.repository.query(`
      select count(1) as total from internet_celebrity_group
      where internet_celebrity_group.id not in (
        select platform.ic_group from platform
        inner join setting on setting.value = platform.platform
        where setting.key = 'level3'
      ) and internet_celebrity_group.type = 0
      and LOWER(name) like ?
    `,[`%${keyword.toLocaleLowerCase()}%`, skip, take])
    
    return {data,total:Number(total[0].total)}
  }

  async findAll_ByUser_Ic_Info_NoPage(keyword: string, id_card: string): Promise<any>{
    let where = `LOWER(wx_user.name) like ?`
    if(id_card){
      where = `wx_user.id_card = ?`
    }
    let data:any = await this.repository.query(`
      select distinct internet_celebrity_group.id,wx_user.id_card as wx_user_id_card,wx_user.name as wx_user_name
      from internet_celebrity_group
      inner join wx_user on wx_user.openid = internet_celebrity_group.wx_user
      where internet_celebrity_group.type = 2
        and ${where}
      order by internet_celebrity_group.id desc
    `,[id_card || `%${keyword.toLocaleLowerCase()}%`])
    return data
  }


  async findAll_ByUser_Ic_Info(skip: number, take: number, keyword: string): Promise<{data:[],total:number}>{
    let data:any = []
    let total = []

    let userList = await this.repository.query(`
      select distinct wx_user.name as wx_user_name, wx_user.avatar_img as wx_user_avatar_img,internet_celebrity_group.id
      from wx_user
      inner join internet_celebrity_group on internet_celebrity_group.wx_user = wx_user.openid
      inner join platform on platform.ic_group = internet_celebrity_group.id
      inner join internet_celebrity on internet_celebrity.ic_group = internet_celebrity_group.id and internet_celebrity.platform = platform.id
      where internet_celebrity_group.type = 2
        and (LOWER(internet_celebrity.name) like ? or LOWER(wx_user.name) like  ?) and platform.platform is not null and platform.platform != ''
      order by internet_celebrity_group.id desc
      limit ?,?
    `,[`%${keyword.toLocaleLowerCase()}%`,`%${keyword.toLocaleLowerCase()}%`, skip, take])

    let whereSql = []
    userList.map(e => {
      whereSql.push(`internet_celebrity_group.id = ?`)
    })
    if(whereSql.length > 0){
      data = await this.repository.query(`
        select distinct internet_celebrity_group.id,wx_user.id_card as wx_user_id_card,wx_user.name as wx_user_name, wx_user.avatar_img as wx_user_avatar_img,
          platform.platform,internet_celebrity.name as ic_name,internet_celebrity.img,internet_celebrity.avatar_img,internet_celebrity.account
        from internet_celebrity_group
        inner join platform on platform.ic_group = internet_celebrity_group.id
        inner join internet_celebrity on internet_celebrity.ic_group = internet_celebrity_group.id and internet_celebrity.platform = platform.id
        inner join wx_user on wx_user.openid = internet_celebrity_group.wx_user
        where (${whereSql.join(' or ')}) and platform.platform is not null and platform.platform != ''
        order by internet_celebrity_group.id desc
      `, userList.map(e => e.id))
    }
    total = await this.repository.query(`
      select count(1) as total
      from (
        select distinct wx_user.name
        from wx_user
        inner join internet_celebrity_group on internet_celebrity_group.wx_user = wx_user.openid
        inner join platform on platform.ic_group = internet_celebrity_group.id
        inner join internet_celebrity on internet_celebrity.ic_group = internet_celebrity_group.id and internet_celebrity.platform = platform.id
        where internet_celebrity_group.type = 2
          and (LOWER(internet_celebrity.name) like ? or LOWER(wx_user.name) like ?) and platform.platform is not null and platform.platform != ''
      ) a
    `,[`%${keyword.toLocaleLowerCase()}%`,`%${keyword.toLocaleLowerCase()}%`])
    
    return {data,total:Number(total[0].total)}
  }

  async findAll_ByUser_NoPage(wx_user: string, keyword: string, byAccount?: boolean): Promise<InternetCelebrityGroup[]>{
    if(byAccount){
      return this.repository.query(`
        select internet_celebrity_group.id, internet_celebrity.account as name, internet_celebrity_group.name as ic_name from internet_celebrity_group
        inner join internet_celebrity on internet_celebrity.ic_group = internet_celebrity_group.id
        where internet_celebrity.account like ?
        limit 0,50
      `,[`%${keyword}%`])
    }else{
      return this.repository.query(`
        select *,
          (
            select account from internet_celebrity
            where internet_celebrity.ic_group = internet_celebrity_group.id
            limit 0,1
          ) as account
        from internet_celebrity_group
        where LOWER(internet_celebrity_group.name) like LOWER(?)
        limit 0,50
      `,[`%${keyword}%`])
    }
  }

  async findAll_NoPage(): Promise<InternetCelebrityGroup[]>{
    return this.repository.query(`
      select * from internet_celebrity_group
    `,[])
  }
  
  async remove(id: number): Promise<void> {
    let findInternetCelebrity = await this.internetCelebrityRepository.query(`
      select * from internet_celebrity
      where ic_group = ?
    `,[id])
    let db: DataBase = new DataBase()
    let connection = await db.getConnection()
    const queryRunner = connection.createQueryRunner()
    await queryRunner.connect()
    // 开始事务
    await queryRunner.startTransaction()
    try {
      await this.repository.createQueryBuilder(null,queryRunner).delete().where({id:id}).execute()
      //删除所有平台信息
      await this.platformRepository.createQueryBuilder(null,queryRunner).delete().where({ic_group:id}).execute()
      //删除所有网红信息
      await this.internetCelebrityRepository.createQueryBuilder(null, queryRunner).delete().where({ic_group: id}).execute()
      //查询网红下所有视频
      let videos = await this.videoRepository.find({where:{ic_group: id}})
      //修改所有视频下答案的审核状态为未审核
      await this.answerRepository.createQueryBuilder(null, queryRunner).update({check: 0, update_time: new Date()}).where({video_id: In(videos.map(e => e.id))}).execute()
      //清空所有视频的答案
      await this.videoRepository.createQueryBuilder(null, queryRunner).update({ic_group: null, original: 0}).where({ic_group: id}).execute()
      
      //如果视频大于3，记录视频列表
      if(videos.length > 3){
        let deleteList: InternetCelebrityGroupDeleteInVideo[] = []
        findInternetCelebrity.map(e => {
          videos.map(c => {
            let addDeleteInVideo = new InternetCelebrityGroupDeleteInVideo()
            addDeleteInVideo.account = e.account
            addDeleteInVideo.name = e.name
            addDeleteInVideo.video_id = c.id
            addDeleteInVideo.create_time = new Date()
            deleteList.push(addDeleteInVideo)
          })
        })
        console.log(deleteList,'deleteList')
        await this.internetCelebrityGroupDeleteInVideoRepository.createQueryBuilder(null, queryRunner)
          .insert()
          .into(InternetCelebrityGroupDeleteInVideo)
          .values(deleteList)
          .execute()
      }

      await queryRunner.commitTransaction()
      await queryRunner.release();
    } catch (err) {
      // 有错误做出回滚更改
      await queryRunner.rollbackTransaction()
      await queryRunner.release();
      return err
    }
  }
}
